<?php

namespace App\Models\OpenShop\InvestmentPromotion;

use App\Enums\OpenShop\InvestmentPromotion\SiteMissionEnum;
use App\Enums\OpenShop\MissionTemplateEnum;
use App\Models\BaseModel;
use App\Models\Clickhouse\OrderGoods\StoreCHModel;
use App\Models\Kms\User\KmsUser;
use App\Models\OpenShop\Common\OpenShopOrderManagerModel;
use App\Models\OpenShop\Site\OpenShopMissionTemplateModel;
use App\Models\OpenShop\SiteLocation\OpenShopSiteLocationModel;
use App\Models\Shop\ShopModel;
use App\Models\Traits\KfSoftDeletes;
use App\Service\Kms\Home\HomeService;
use DateTimeInterface;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\HasManyThrough;
use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Database\Eloquent\Relations\HasOneThrough;
use Kuafu\LaravelClickHouse\Database\Eloquent\Builder;
use Tinderbox\Clickhouse\Exceptions\ClientException;

class OpenShopSiteMissionModel extends BaseModel
{
    use KfSoftDeletes;

    protected $fillable = [
        'missionId',
        'missionType',
        'mainStep',
        'stepStatus',
        'missionName',
        'status',
        'orderNo',
        'dealUid',
        'orderStatus',
        'isShow',
        'handlerType',
        'expiredAt',
        'completeAt',
        'createdAt',
        'createdByUid',
        'updatedAt',
        'updatedByUid',
        'isDeleted',
    ];

    protected $table = 'open_shop_site_mission';

    protected function serializeDate(DateTimeInterface $date)
    {
        return $date->format("Y-m-d H:i:s");
    }

    /**
     * @return Hasone
     */
    public function openShopSignOrderRel(): Hasone
    {
        return $this->hasOne(OpenShopSignOrderModel::class, 'orderNo', 'orderNo');
    }

    public function baseInfoRel(): HasOne
    {
        return $this->hasOne(OpenShopUserBaseInfoModel::class, 'orderNo', 'orderNo');

    }

    public function openShopUserIdentityCardRel(): HasOne
    {
        return $this->hasOne(
            OpenShopUserIdentityCardModel::class,
            'orderNo',
            'orderNo',
        );
    }

    public function siteLocationRel(): HasOne
    {
        return $this->hasOne(OpenShopSiteLocationModel::class, "orderNo", "orderNo")->whereIn('source',
            [OpenShopSiteLocationModel::SOURCE_OPEN_SHOP, OpenShopSiteLocationModel::SOURCE_HOUSING]);
    }

    public function addressRel(): HasOne
    {
        return $this->hasOne(OpenShopAddressModel::class, 'orderNo', 'orderNo');
    }

    /**
     * 更新任务状态
     *
     * @param int $stepStatus
     * @param int $status
     * @return int
     */
    public function updateData(string $orderNo, int $stepStatus, array $updateData)
    {
        return self::query()->where('orderNo', $orderNo)->where('stepStatus', $stepStatus)
                   ->update($updateData);
    }

    /**
     * check exist
     *
     * @param string $orderNo
     * @param int $stepStatus
     * @return bool
     */
    public function isExist(string $orderNo, int $stepStatus = -1)
    {
        $info = self::getInfo($orderNo, $stepStatus);

        if ($info) {
            return true;
        } else {
            return false;
        }
    }

    public function getInfo(string $orderNo, int $stepStatus = -1)
    {
        $info = self::query()
                    ->where('orderNo', $orderNo)
                    ->when($stepStatus != -1, function ($query) use ($stepStatus) {
                        $query->where('stepStatus', $stepStatus);
                    })
                    ->first();

        return $info;

    }


    /**
     * @return HasOne
     */
    public function spaceDesignCostMappingRel(): HasOne
    {
        return $this->hasOne(OpenShopSpaceDesignCostMappingModel::class, "orderNo", "orderNo");
    }

    /**
     * 完成支线任务
     * @param string $orderNo
     * @param int $stepStatus
     * @return bool
     */
    public static function finishBranchMission(string $orderNo, int $stepStatus): bool
    {
        $siteMission = OpenShopSiteMissionModel::query()
                                               ->where('orderNo', $orderNo)
                                               ->where('stepStatus', $stepStatus)
                                               ->where('status', SiteMissionEnum::STATUS_1)
                                               ->first();
        if (!$siteMission) {
            return false;
        }

        $siteMission->status = SiteMissionEnum::STATUS_2;
        $siteMission->completeAt = time();
        return $siteMission->save();
    }

    /**
     * 强制删除任务
     * @param string $orderNo
     * @param int $stepStatus
     * @return int
     */
    public static function delMission(string $orderNo, int $stepStatus): int
    {
        $site = OpenShopSiteMissionModel::query()
                                        ->where('orderNo', $orderNo)
                                        ->where('stepStatus', $stepStatus)
                                        ->where('status', SiteMissionEnum::STATUS_1)
                                        ->orderByDesc('id')
                                        ->first();
        if ($site) {

            // 第一个主任务不能删
            return $site->update(['isDeleted' => 1]);
        }

        return 0;
    }

    /**
     * 更改经理人，改变任务处理人
     * @param int $oriDealUid
     * @param int $dealUid
     * @return int
     */
    public static function changeManagerUid(string $orderNo, int $dealUid, int $handlerRole): int
    {
        $stepStatusList = OpenShopMissionTemplateModel::query()
                                                      ->withoutGlobalScope('isDel')
                                                      ->where('handlerRole', $handlerRole)
                                                      ->where('handlerType', MissionTemplateEnum::HANDLER_TYPE_STAFF)
                                                      ->pluck('stepStatus')
                                                      ->toArray();

        if ($handlerRole == MissionTemplateEnum::HANDLER_ROLE_3) {
            $stepStatusList[] = MissionTemplateEnum::STEP_STATUS_13;
        }

        return self::query()
                   ->where('orderNo', $orderNo)
                   ->whereIn('stepStatus', $stepStatusList)
                   ->where('status', SiteMissionEnum::STATUS_1)
                   ->update(['dealUid' => $dealUid]);
    }

    /**
     * 获取最新的已完成的任务id
     * @param string $orderNo
     * @return int
     */
    public static function getLastFinishSiteId(string $orderNo, int $stepStatus): int
    {
        return (int)OpenShopSiteMissionModel::query()
                                            ->where('orderNo', $orderNo)
                                            ->where('stepStatus', $stepStatus)
                                            ->where('status', SiteMissionEnum::STATUS_2)
                                            ->orderByDesc('id')
                                            ->value('id');
    }

    //查询对应任务
    public static function getTaskExist(string $orderNo, int $stepStatus): bool
    {
        return OpenShopSiteMissionModel::query()->where("orderNo", $orderNo)
                                       ->where("status", SiteMissionEnum::STATUS_2)
                                       ->where("stepStatus", $stepStatus)
                                       ->exists();
    }





    public function getOrderManagerRel(): HasManyThrough
    {
        return $this->hasManyThrough(
            OpenShopOrderManagerModel::class,
            OpenShopMainProcessModel::class,
            'orderNo',
            'mainProcessId',
            'orderNo',
            'id',
        );
    }

    /**
     * @param int $regionSelectionType
     * @param string $region
     * @param string $regionValue
     * @return \Illuminate\Database\Eloquent\Builder|mixed
     */
    public static function buildHomeSearchQuery(int $regionSelectionType, string $region, string $regionValue)
    {
        $query = function ($query) {
            $query->where("id", 0);
        };
        switch ($regionSelectionType) {
            case HomeService::REGION_SELECTION_TYPE_1:
                $regionRel = attributeGet(
                    OpenShopOrganizationManageModel::allOrganizationManage()->where("name", $region)->first(),
                    "regionRel",
                    collect([])
                );

                if (!empty($provinceCodes = $regionRel->pluck("provinceCode")->toArray())) {
                    $orderNos = OpenShopAddressModel::query()
                                                    ->whereIn("provinceCode", $provinceCodes)
                                                    ->pluck("orderNo")
                                                    ->toArray();
                    if (!empty($orderNos)) {
                        $query = function ($query) use ($orderNos) {
                            return $query->whereIn("orderNo", $orderNos);
                        };
                    }
                }
                break;
            case HomeService::REGION_SELECTION_TYPE_2:
                $orderNos = OpenShopAddressModel::query()
                                                ->where("provinceCode", $regionValue)
                                                ->pluck("orderNo")
                                                ->toArray();

                if (!empty($orderNos)) {
                    $query = function ($query) use ($orderNos) {
                        return $query->whereIn("orderNo", $orderNos);
                    };
                }
                break;
            case HomeService::REGION_SELECTION_TYPE_3:
                $orderNos = OpenShopAddressModel::query()
                                                ->where("cityCode", $regionValue)
                                                ->pluck("orderNo")
                                                ->toArray();

                if (!empty($orderNos)) {
                    $query = function ($query) use ($orderNos) {
                        return $query->whereIn("orderNo", $orderNos);
                    };
                }
                break;
            case HomeService::REGION_SELECTION_TYPE_0:
                $query = null;
                break;
        }
        return self::query()->when($query, function ($subQuery) use ($query) {
            return $subQuery->where($query);
        });
    }

    public function fsUserRel(): HasOne
    {
        return $this->hasOne(KmsUser::class, 'rmsUserId', 'dealUid');
    }
}
